package com.family.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.family.common.result.Result;
import com.family.model.system.SysMenu;
import com.family.model.system.SysUser;
import com.family.model.system.SysUserRole;
import com.family.model.vo.AssignRoleVo;
import com.family.model.vo.RouterVo;
import com.family.model.vo.SysUserQueryVo;
import com.family.system.mapper.SysMenuMapper;
import com.family.system.mapper.SysRoleMapper;
import com.family.system.mapper.SysUserMapper;
import com.family.system.mapper.SysUserRoleMapper;
import com.family.system.service.SysUserService;
import com.family.system.utils.RouterHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName SysUserServiceImpl
 * @Date 2023-05-08 14:28
 * @AUTHOR family
 **/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    public IPage<SysUser> selectPage(Page<SysUser> sysUserPage, SysUserQueryVo sysUserQueryVo) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(sysUserQueryVo.getKeyword())) {
            queryWrapper.like(SysUser::getPhone, sysUserQueryVo.getKeyword()).or()
                    .like(SysUser::getUsername, sysUserQueryVo.getKeyword()).or()
                    .like(SysUser::getName, sysUserQueryVo.getKeyword());
        }
        if (!StringUtils.isEmpty(sysUserQueryVo.getCreateTimeBegin())) {
            queryWrapper.ge(SysUser::getCreateTime, sysUserQueryVo.getCreateTimeBegin());
        }
        if (!StringUtils.isEmpty(sysUserQueryVo.getCreateTimeBegin())) {
            queryWrapper.le(SysUser::getCreateTime, sysUserQueryVo.getCreateTimeEnd());
        }
        IPage<SysUser> userPage = sysUserMapper.selectPage(sysUserPage, queryWrapper);
        redisTemplate.opsForValue().set("userList" + userPage.getCurrent(), userPage, 1, TimeUnit.HOURS);
        return userPage;
    }

    @Override
    public Result<Object> updateStatus(Long id, Integer status) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setStatus(status);
        int row = sysUserMapper.updateById(sysUser);
        if (row < 1) {
            return Result.fail();
        }
        return Result.ok();
    }

    @Override
    public Map<String, Object> getRolesByUserId(Long userId) {
        //获取所有的角色信息
        Object allRoles = redisTemplate.opsForValue().get("allRoles");
        if (allRoles == null) {
            allRoles = sysRoleMapper.selectList(null);
            redisTemplate.opsForValue().set("allRoles", allRoles);
        }
        //获取用户的角色信息
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRole::getUserId, userId);
        List<SysUserRole> userRoleList = sysUserRoleMapper.selectList(queryWrapper);
        //获取用户已分配的角色id
        List<Long> userRoleIds = new ArrayList<>();
        for (SysUserRole sysUserRole : userRoleList) {
            userRoleIds.add(sysUserRole.getRoleId());
        }
        //封装数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("allRoles", allRoles);
        map.put("userRoleIds", userRoleIds);
        return map;
    }

    @Override
    public void doAssign(AssignRoleVo assignRoleVo) {
        Long userId = assignRoleVo.getUserId();
        List<Long> roleIds = assignRoleVo.getRoleIdList();
        //根据用户id删除原来分配的角色
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRole::getUserId, userId);
        sysUserRoleMapper.delete(queryWrapper);
        //添加新的用户角色信息
        for (Long roleId : roleIds) {
            if (roleId != null) {
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserId(userId);
                sysUserRole.setRoleId(roleId);
                sysUserRoleMapper.insert(sysUserRole);
            }
        }
    }

    @Override
    public SysUser getByUsername(String username) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUsername, username);
        return sysUserMapper.selectOne(queryWrapper);
    }

    @Override
    public Map<String, Object> getUserInfoByUserId(Long userId) {
        //查询用户信息
        SysUser sysUser = sysUserMapper.selectById(userId);
        //调用根据用户id获取权限菜单的方法
        List<SysMenu> menuList = getUserMenusByUserId(userId);
        //将userMenuList转换为菜单树
        menuList = SysMenuServiceImpl.buildTree(menuList);
        //将菜单树转换为路由
        List<RouterVo> routerList = RouterHelper.buildRouters(menuList);
        //获取用户的按钮权限标识符
        List<String> btnPermsByUserId = getUserBtnPermsByUserId(userId);
        //创建一个Map
        Map<String, Object> map = new HashMap<>();
        //当前权限控制使用不到，我们暂时忽略
        map.put("name", sysUser.getName());
        map.put("roles", new HashSet<>());
        map.put("avatar", "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        map.put("routers", routerList);
        map.put("buttons", btnPermsByUserId);
        return map;
    }

    @Override
    public List<String> getUserBtnPermsByUserId(Long userId) {
        //调用根据用户id获取权限菜单的方法
        List<SysMenu> menuList = getUserMenusByUserId(userId);
        //创建一个保存用户按钮权限标识的List
        ArrayList<String> buttonPermissons = new ArrayList<>();
        //遍历权限菜单
        for (SysMenu sysMenu : menuList) {
            if (sysMenu.getType() == 2) {
                buttonPermissons.add(sysMenu.getPerms());
            }
        }
        return buttonPermissons;
    }

    //根据用户id查询用户的权限菜单
    private List<SysMenu> getUserMenusByUserId(Long userId) {
        List<SysMenu> userMenuList = null;
        //判断该用户是否是系统管理员
        if (userId == 1L) {
            userMenuList = sysMenuMapper.selectList(new QueryWrapper<SysMenu>().eq("status", 1).orderByAsc("sort_value"));
        } else {
            userMenuList = sysMenuMapper.selectMenuListByUserId(userId);
        }
        return userMenuList;
    }
}
